# -*- coding: utf-8 -*-
import os
import time

import bs4, requests, re, json, lxml
import xlrd
import xlwt
from requests.cookies import RequestsCookieJar
# 控制台输出移除SSL认证警告
import urllib3
from xlwt import Workbook
from Excel_Operate import *

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

git_url = 'https://git.mingyuanyun.com/users/sign_in'
_cache_file = {}
path = r'D:\桌面'
headers = {
    'Host': 'git.mingyuanyun.com',
    'Connection': 'keep-alive',
    'Accept': '*/*',
    'X-Requested-With': 'XMLHttpRequest',
    'X-PJAX': 'true',
    'X-AUSERNAME': 'wup06',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Site': 'same-origin',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-CN,zh;q=0.9',
}

LoginHeaders = {
    'Host': 'git.mingyuanyun.com',
    'Connection': 'keep-alive',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
    'Sec-Fetch-Site': 'none',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-Dest': 'document',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-CN,zh;q=0.9'
}
# 设置代理，用户fiddler抓取
proxies = {
    "http": "127.0.0.1:8888"
}
def tags_val(tag, key='', index=0):
    '''
    return html tag list attribute @key @index
    if @key is empty, return tag content
    '''
    if len(tag) == 0 or len(tag) <= index:
        return ''
    elif key:
        txt = tag[index].get(key)
        return txt.strip(' \t\r\n') if txt else ''
    else:
        txt = tag[index].text
        return txt.strip(' \t\r\n') if txt else ''


def tag_val(tag, key=''):
    '''
    return html tag attribute @key
    if @key is empty, return tag content
    '''
    if tag is None:
        return ''
    elif key:
        txt = tag.get(key)
        return txt.strip(' \t\r\n') if txt else ''
    else:
        txt = tag.text
        return txt.strip(' \t\r\n') if txt else ''

# 初始化session，后续请求就能自动带上cookies
sess = requests.session()

def get_token():
    resp = sess.get(
        url=git_url,
        headers=LoginHeaders, proxies=proxies, verify=False)
    #通过bs4解析html
    soup = bs4.BeautifulSoup(resp.text, 'lxml')
    tags = soup.select('[name="csrf-token"]')
    if resp.status_code == 200:
        token = tags_val(tags, "content", 0)
        return token
    else:
        print ('token获取失败')

# 登录
def login():
    token = get_token()
    header = {
        'Host': 'git.mingyuanyun.com',
        'Connection': 'keep-alive',
        'Content-Length': '170',
        'Cache-Control': 'max-age=0',
        'Upgrade-Insecure-Requests': '1',
        'Origin': 'https://git.mingyuanyun.com',
        'Content-Type': 'application/x-www-form-urlencoded',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
        'Sec-Fetch-Site': 'same-origin',
        'Sec-Fetch-Mode': 'navigate',
        'Sec-Fetch-User': '?1',
        'Sec-Fetch-Dest': 'document',
        'Referer': 'https://git.mingyuanyun.com/users/sign_in',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh;q=0.9',
    }
    data = {
        'utf8': '✓',
        'authenticity_token': token,
        'username': 'wup06',
        'password': 'xxxxx',
    }
    cookie_jar = RequestsCookieJar()
    # print(sess.cookies(['_gitlab_session']))
    # 将cookiejar转换为字典形式的数据:{'_gitlab_session': '4774884897f7ea1ab2a48ed2caab4fa6'}
    get_cookies_dict = requests.utils.dict_from_cookiejar(sess.cookies)
    cookie_jar.set("sidebar_collapsed", "false")
    # for k,v in get_cookies_dict.items():
    #     cookie_jar.set(k, v)
    cookies = cookie_jar

    resp = sess.post(
        url="https://git.mingyuanyun.com/users/auth/ldapmain/callback",
        headers=header, data=data, cookies = cookies, proxies=proxies, verify=False)
    if resp.status_code == 200:
        pass
    else:
        print ('登录失败')

def request(project,branch_name,index=0):
    params = ''
    if index != 0:
        params = f'?limit=40&offset={40*index}'
    if 'app' in project.lower():
        url = f"https://git.mingyuanyun.com/platform/gzl/MyBPM/commits/{branch_name}{params}"
    else:
        url = f"https://git.mingyuanyun.com/platform/lczx/process_engine/commits/{branch_name}{params}"
    resp = sess.get(url)
    return resp

def get_content(project,branch_name, datatime):
    date_day_list, resp, commit_contents = get_last_date(branch_name, project)
    result = [['提交人','提交时间','提交主题','更多']]
    index = 0
    # 当页返回的date_day为list，list中存在大于等于指定日期时，返回True，全部都小于指定日期，则跳出循环
    while True in list(map(lambda x:x>=datatime,date_day_list)):
        if resp.status_code == 200:
            for a in commit_contents:
                # 得到class="commit-content qa-commit-content"的父元素列表
                for parent in a.parents:
                    # 获取父元素中data-day的属性值
                    data = parent.get('data-day')
                    # data-day值不为None且大于指定日期
                    if data is not None and data >= datatime:
                        # 获取.commiter的元素组
                        commits = a.select('.commiter')
                        content = []
                        for commit in commits:
                            # 获取.commiter下的.commit-author-link.has-tooltip元素
                            author = commit.select('.commit-author-link.has-tooltip')
                            # 获取.commiter下的time元素
                            time = commit.select('time')
                            # 组成提交者+提交时间
                            # committer = f'{author[0].text}_{time[0].attrs["title"]}'
                            committer = f'{author[0].text}'
                            commit_time = f'{time[0].attrs["title"]}'
                            titles = commit.parent.select('a.commit-row-message.item-title')
                            title_text= ''
                            for title in titles:
                                title_text += title.text
                            # 如果是合并分支记录，直接跳出
                            if 'Merge branch' in title_text:
                                break
                            # 获取提交记录的更多
                            more = commit.parent.pre
                            if more is None:
                                content.extend([committer,commit_time,title_text,''])
                                # content = f'【{committer}】: {title_text}'
                            else:
                                content.extend([committer, commit_time, title_text, more.text])
                                # content = f'【{committer}】: {title_text}\n---更多{more.text}'
                        if content != []:
                            result.append(content)
        else:
            print ('获取失败')
            return None
        # 根据循环条件，获取后续的页面
        index += 1
        date_day_list, resp, commit_contents = get_last_date(branch_name, project,index)
        # 返回已提交bug的列表
    return result


def get_last_date(branch_name, project, index=0):
    """
    获取最后日期
    :param branch_name:
    :param project: app或者engine
    :param index: 从0开始
    :return:
    """
    resp = request(project, branch_name,index)
    # 通过bs4解析html
    soup = bs4.BeautifulSoup(resp.text, 'lxml')
    commit_contents = soup.select('[class="commit-content qa-commit-content"]')
    # 获取本页最小日期，用于判断是否需要继续请求
    date_day_tags = soup.select('#commits-list>.commits-row')
    date_day_list = list(map(lambda ele: ele.get('data-day'), date_day_tags))
    return date_day_list, resp, commit_contents

def git_action(project,branch_name, datatime):
    login()
    return get_content(project,branch_name, datatime)

def main(projects, branch_name, init_time, sava_path='C:'):
    """
    执行获取git提交
    :param projects:项目，app和engine
    :param branch_name: 分支，Test、Pre等等
    :param init_time: 初始时间
    :param sava_path: 保存目录，需要目录存在，默认C盘
    :return:
    """
    current_date = time.strftime('%Y-%m-%d_%H-%M-%S')
    file = rf'{sava_path}\{branch_name}分支{init_time}到{current_date}.xls'
    for project in projects:
        git_content:list = git_action(project, branch_name, init_time)
        print(f"\n*****************************{project}提交记录*****************************")
        print(git_content)
        for row_num, row_content in enumerate(git_content):
            for col_num,col_content in enumerate(row_content):
                write_excel(file,row_num,col_num,col_content,project)
        #     print(summary.replace(u'\xa0', u' '))
        #     print(summary)
#
# if __name__ == '__main__':
#     # 项目：应用或者引擎
#     projects = ['app','engine']
#     # 需要查询的分支，截止时间
#     main(projects,'Pre','2022-03-31')
